package io.renren.modules.quickService.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.modules.app.form.AttachmentForm;
import io.renren.modules.app.service.UserService;
import io.renren.modules.quickService.constants.AppointType;
import io.renren.modules.quickService.constants.AttachmentType;
import io.renren.modules.quickService.constants.AuditStatus;
import io.renren.modules.quickService.constants.OrderStatus;
import io.renren.modules.quickService.dao.OrderDao;
import io.renren.modules.quickService.entity.OrderEntity;
import io.renren.modules.quickService.entity.OrderOperationEntity;
import io.renren.modules.quickService.entity.UserEntity;
import io.renren.modules.quickService.entity.UserExtraEntity;
import io.renren.modules.quickService.service.AttachmentService;
import io.renren.modules.quickService.service.OrderOperationService;
import io.renren.modules.quickService.service.OrderService;
import io.renren.modules.quickService.service.UserExtraService;
import io.renren.modules.quickService.vo.OrderOperate;
import io.renren.modules.quickService.vo.OrderStatistics;
import io.renren.modules.sys.entity.SysUserEntity;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;


@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {
    @Autowired
    UserExtraService userExtraService;
    @Autowired
    UserService appUserService;
    @Autowired
    OrderOperationService orderOperationService;
    @Autowired
    private AttachmentService attachmentService;

    @Override
    public PageUtils queryPage2(Map<String, Object> params) {
        Page<OrderEntity> page = this.selectPage(
                new Query<OrderEntity>(params).getPage(),
                new EntityWrapper<OrderEntity>()
                        .eq(isNotBlank(params.get("status")), "status", params.get("status"))
                        .eq(isNotBlank(params.get("adminCode")), "admin_code", params.get("adminCode"))
                        .eq(isNotBlank(params.get("name")), "customer_name", params.get("name"))
                        .eq(isNotBlank(params.get("phone")), "customer_phone", params.get("phone"))
                        .eq(isNotBlank(params.get("takerName")), "order_taker_name", params.get("takerName"))
                        .orderBy("create_time", false)
        );
        return new PageUtils(page);
    }

    private boolean isNotBlank(Object object) {
        if (object != null) {
            return StringUtils.isNotBlank(object.toString());
        }
        return false;
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page<OrderEntity> page = this.selectPage(
                new Query<OrderEntity>(params).getPage(),
                new EntityWrapper<OrderEntity>()
                        .eq(params.get("status") != null, "status", params.get("status"))
                        .eq(params.get("adminCode") != null, "admin_code", params.get("adminCode"))
                        .eq(params.get("orderTakerId") != null, "order_taker_id", params.get("orderTakerId"))
                        .orderBy("create_time", false)
        );

        return new PageUtils(page);
    }

    @Override
    public boolean takeOrder(OrderOperate orderOperate, Long userId) {
        try {
            UserEntity userEntity = appUserService.selectById(userId);
            UserExtraEntity userExtraEntity = userExtraService.queryUserExtraByMobile(userEntity.getMobile());
            OrderEntity order = baseMapper.selectById(orderOperate.getOrderId());
            order.setOrderTakerId(userEntity.getUserId());
            order.setOrderTakerName(userExtraEntity.getExtraName());
            if (checkOrderStatus(order.getStatus(), OrderStatus.SCHEDULING.getKey())) {
                order.setStatus(OrderStatus.SCHEDULING.getKey());
                baseMapper.updateById(order);
                Long operateId = saveOperation(userExtraEntity, order.getId(), "师傅接单");
                saveAttachmentList(orderOperate.getAttachmentListForm(), AttachmentType.ORDER_TAKE.getKey(), operateId);
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 保存操作附件
     *
     * @param attachmentsForms attachmentsForms
     * @param attachmentType   attachmentType
     * @param operateId        operateId
     */
    private void saveAttachmentList(List<AttachmentForm> attachmentsForms, String attachmentType, Long operateId) {
        attachmentService.saveAttachments(attachmentsForms, "" + operateId, attachmentType);
    }

    @Override
    public boolean contend(OrderOperate orderOperate, Long userId) {
        try {
            UserEntity userEntity = appUserService.selectById(userId);
            UserExtraEntity userExtraEntity = userExtraService.queryUserExtraByMobile(userEntity.getMobile());
            OrderEntity order = baseMapper.selectById(orderOperate.getOrderId());
            order.setOrderTakerId(userEntity.getUserId());
            order.setOrderTakerName(userExtraEntity.getExtraName());
            order.setAppointType(AppointType.INITIATIVE.getKey());
            if (checkOrderStatus(order.getStatus(), OrderStatus.SCHEDULING.getKey())) {
                order.setStatus(OrderStatus.SCHEDULING.getKey());
                baseMapper.updateById(order);
                Long operateId = saveOperation(userExtraEntity, order.getId(), "师傅抢单");
                saveAttachmentList(orderOperate.getAttachmentListForm(), AttachmentType.ORDER_TAKE.getKey(), operateId);
                return true;
            } else {
                return false;
            }

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean refuseOrder(OrderOperate orderOperate, Long userId) {
        try {
            UserEntity userEntity = appUserService.selectById(userId);
            UserExtraEntity userExtraEntity = userExtraService.queryUserExtraByMobile(userEntity.getMobile());
            OrderEntity order = baseMapper.selectById(orderOperate.getOrderId());
            order.setOrderTakerId(Long.getLong("0"));
            order.setOrderTakerName("");
            if (checkOrderStatus(order.getStatus(), OrderStatus.NEW_ORDER.getKey())) {
                order.setStatus(OrderStatus.NEW_ORDER.getKey());
                baseMapper.updateById(order);
                Long operateId = saveOperation(userExtraEntity, order.getId(), "师傅拒接单：" + orderOperate.getExplanation());
                saveAttachmentList(orderOperate.getAttachmentListForm(), AttachmentType.ORDER_TAKE.getKey(), operateId);
            } else {
                return false;
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean visiting(OrderOperate orderOperate, Long userId) {
        try {
            UserEntity userEntity = appUserService.selectById(userId);
            UserExtraEntity userExtraEntity = userExtraService.queryUserExtraByMobile(userEntity.getMobile());
            OrderEntity order = baseMapper.selectById(orderOperate.getOrderId());
            if (checkOrderStatus(order.getStatus(), OrderStatus.VISITING.getKey())) {
                order.setStatus(OrderStatus.VISITING.getKey());
                baseMapper.updateById(order);
                Long operateId = saveOperation(userExtraEntity, order.getId(), "师傅看现场:" + orderOperate.getExplanation());
                saveAttachmentList(orderOperate.getAttachmentListForm(), AttachmentType.ORDER_TAKE.getKey(), operateId);
            } else {
                return false;
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean agreement(OrderOperate orderOperate, Long userId) {
        try {
            UserEntity userEntity = appUserService.selectById(userId);
            UserExtraEntity userExtraEntity = userExtraService.queryUserExtraByMobile(userEntity.getMobile());
            OrderEntity order = baseMapper.selectById(orderOperate.getOrderId());
            if (checkOrderStatus(order.getStatus(), OrderStatus.AGREEMENT.getKey())) {
                order.setStatus(OrderStatus.AGREEMENT.getKey());
                baseMapper.updateById(order);
                Long operateId = saveOperation(userExtraEntity, order.getId(), "签订协议:" + orderOperate.getExplanation());
                saveAttachmentList(orderOperate.getAttachmentListForm(), AttachmentType.ORDER_TAKE.getKey(), operateId);
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean confirm(OrderOperate orderOperate, Long userId) {
        try {
            UserEntity userEntity = appUserService.selectById(userId);
            UserExtraEntity userExtraEntity = userExtraService.queryUserExtraByMobile(userEntity.getMobile());
            OrderEntity order = baseMapper.selectById(orderOperate.getOrderId());
            if (checkOrderStatus(order.getStatus(), OrderStatus.MIDDLE_CONFIRM.getKey())) {
                order.setStatus(OrderStatus.MIDDLE_CONFIRM.getKey());
                baseMapper.updateById(order);
                Long operateId = saveOperation(userExtraEntity, order.getId(), "中期验收:" + orderOperate.getExplanation());
                saveAttachmentList(orderOperate.getAttachmentListForm(), AttachmentType.ORDER_TAKE.getKey(), operateId);
            } else {
                return false;
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean complete(OrderOperate orderOperate, Long userId) {
        try {
            UserEntity userEntity = appUserService.selectById(userId);
            UserExtraEntity userExtraEntity = userExtraService.queryUserExtraByMobile(userEntity.getMobile());
            OrderEntity order = baseMapper.selectById(orderOperate.getOrderId());
            if (checkOrderStatus(order.getStatus(), OrderStatus.COMPLETED_CONSTRUCTION.getKey())) {
                order.setStatus(OrderStatus.COMPLETED_CONSTRUCTION.getKey());
                baseMapper.updateById(order);
                Long operateId = saveOperation(userExtraEntity, order.getId(), "完成施工:" + orderOperate.getExplanation());
                saveAttachmentList(orderOperate.getAttachmentListForm(), AttachmentType.ORDER_TAKE.getKey(), operateId);
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean completeAudit(OrderEntity order, SysUserEntity user) {
        baseMapper.updateById(order);
        OrderOperationEntity operation = new OrderOperationEntity();
        try {
            if (AuditStatus.VERIFIED.getKey().equals(order.getAuditStatus())) {
                if (checkOrderStatus(order.getStatus(), OrderStatus.ACCOUNT_CHECKING.getKey())) {
                    order.setStatus(OrderStatus.ACCOUNT_CHECKING.getValue());
                    operation.setOperationDesc("完工审核通过,订单进入对账");
                } else {
                    return false;
                }
            }
            if (AuditStatus.AUDIT_FAILED.getKey().equals(order.getAuditStatus())) {
                if (checkOrderStatus(order.getStatus(), OrderStatus.MIDDLE_CONFIRM.getKey())) {
                    order.setStatus(OrderStatus.MIDDLE_CONFIRM.getKey());
                    operation.setOperationDesc("完工审核通过,进入中期验收");
                } else {
                    return false;
                }
            }
            baseMapper.updateById(order);
            operation.setOperationTime(new Date());
            operation.setOperatorId(user.getUserId());
            operation.setOperatorName("系统管理员:" + user.getUsername());
            operation.setOrderId(order.getId());
            orderOperationService.insert(operation);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean accountChecking(OrderEntity order, SysUserEntity user) {
        baseMapper.updateById(order);
        OrderOperationEntity operation = new OrderOperationEntity();
        try {
            if (checkOrderStatus(order.getStatus(), OrderStatus.FINISHED.getKey())) {
                order.setStatus(OrderStatus.FINISHED.getKey());
                baseMapper.updateById(order);
                operation.setOperationDesc("完成订单");
                operation.setOperationTime(new Date());
                operation.setOperatorId(user.getUserId());
                operation.setOperatorName("系统管理员:" + user.getUsername());
                operation.setOrderId(order.getId());
                orderOperationService.insert(operation);
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean afterSales(OrderEntity order, SysUserEntity user) {
        baseMapper.updateById(order);
        OrderOperationEntity operation = new OrderOperationEntity();
        try {
            if (checkOrderStatus(order.getStatus(), OrderStatus.AFTER_SALES.getKey())) {
                order.setStatus(OrderStatus.AFTER_SALES.getKey());
                baseMapper.updateById(order);
                operation.setOperationDesc("申请售后");
                operation.setOperationTime(new Date());
                operation.setOperatorId(user.getUserId());
                operation.setOperatorName("系统管理员:" + user.getUsername());
                operation.setOrderId(order.getId());
                orderOperationService.insert(operation);
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 设置操作记录
     */
    private Long saveOperation(UserExtraEntity userExtraEntity, Long orderId, String operationDesc) {
        OrderOperationEntity operation = new OrderOperationEntity();
        operation.setOperationDesc(operationDesc);
        operation.setOperationTime(new Date());
        operation.setOperatorId(userExtraEntity.getUserId());
        operation.setOperatorName(userExtraEntity.getExtraName());
        operation.setOrderId(orderId);
        orderOperationService.insertSelective(operation);
        return operation.getId();
    }

    /**
     * ============================================================================
     * 检查订单状态流转是否合法
     * TO_RELEASE("TO_RELEASE", "待发布")
     * ->NEW_ORDER 新订单  管理员操作
     * ============================================================================
     * <p>
     * NEW_ORDER("NEW_ORDER", "新订单")
     * ->TO_RELEASE 待发布  师傅APP拒单
     * ->SCHEDULING 待安排  师傅APP拒单
     * ============================================================================
     * <p>
     * SCHEDULING("SCHEDULING","待安排")
     * ->看现场/签协议/中期验收/完工   师傅APP操作
     * ============================================================================
     * VISITING("VISITING","看现场")
     * ->待安排/签协议/中期验收/完工  师傅APP操作
     * ============================================================================
     * AGREEMENT("AGREEMENT","签协议")
     * ->待安排/看现场/中期验收/完工  师傅APP操作
     * ============================================================================
     * MIDDLE_CONFIRM("MIDDLE_CONFIRM","中期验收")
     * ->待安排/看现场/签协议/完工    师傅APP操作
     * ============================================================================
     * COMPLETED_CONSTRUCTION("COMPLETED", "施工完成")
     * ->待安排/看现场/签协议/中期验收/对账  师傅APP操作
     * ============================================================================
     * ACCOUNT_CHECKING("ACCOUNT_CHECKING","对账")
     * ->已完成    管理员操作
     * ============================================================================
     * FINISHED("FINISHED", "已完成")
     * ->售后 管理员操作
     * ============================================================================
     * AFTER_SALES("AFTER_SALES","售后")
     * ============================================================================
     *
     * @return boolean true合法, false不合法
     */
    private boolean checkOrderStatus(String currentStatus, String targetStatus) {
        if (OrderStatus.TO_RELEASE.getKey().equals(currentStatus)) {
            return (OrderStatus.SCHEDULING.getKey().equals(targetStatus));
        } else if (OrderStatus.NEW_ORDER.getKey().equals(currentStatus)) {
            return (OrderStatus.TO_RELEASE.getKey().equals(targetStatus)
                    || OrderStatus.SCHEDULING.getKey().equals(targetStatus)
                    || OrderStatus.VISITING.getKey().equals(targetStatus));
        } else if (OrderStatus.SCHEDULING.getKey().equals(currentStatus)) {
            return (OrderStatus.VISITING.getKey().equals(targetStatus) ||
                    OrderStatus.AGREEMENT.getKey().equals(targetStatus) ||
                    OrderStatus.MIDDLE_CONFIRM.getKey().equals(targetStatus) ||
                    OrderStatus.COMPLETED_CONSTRUCTION.getKey().equals(targetStatus)
            );
        } else if (OrderStatus.VISITING.getKey().equals(currentStatus)) {
            return (OrderStatus.SCHEDULING.getKey().equals(targetStatus) ||
                    OrderStatus.AGREEMENT.getKey().equals(targetStatus) ||
                    OrderStatus.MIDDLE_CONFIRM.getKey().equals(targetStatus) ||
                    OrderStatus.COMPLETED_CONSTRUCTION.getKey().equals(targetStatus)
            );
        } else if (OrderStatus.AGREEMENT.getKey().equals(currentStatus)) {
            return (OrderStatus.SCHEDULING.getKey().equals(targetStatus) ||
                    OrderStatus.VISITING.getKey().equals(targetStatus) ||
                    OrderStatus.MIDDLE_CONFIRM.getKey().equals(targetStatus) ||
                    OrderStatus.COMPLETED_CONSTRUCTION.getKey().equals(targetStatus)
            );
        } else if (OrderStatus.MIDDLE_CONFIRM.getKey().equals(currentStatus)) {
            return (OrderStatus.SCHEDULING.getKey().equals(targetStatus) ||
                    OrderStatus.VISITING.getKey().equals(targetStatus) ||
                    OrderStatus.AGREEMENT.getKey().equals(targetStatus) ||
                    OrderStatus.COMPLETED_CONSTRUCTION.getKey().equals(targetStatus)
            );
        } else if (OrderStatus.COMPLETED_CONSTRUCTION.getKey().equals(currentStatus)) {
            return (OrderStatus.SCHEDULING.getKey().equals(targetStatus) ||
                    OrderStatus.MIDDLE_CONFIRM.getKey().equals(targetStatus) ||
                    OrderStatus.AGREEMENT.getKey().equals(targetStatus) ||
                    OrderStatus.VISITING.getKey().equals(targetStatus) ||
                    OrderStatus.ACCOUNT_CHECKING.getKey().equals(targetStatus)
            );
        } else if (OrderStatus.ACCOUNT_CHECKING.getKey().equals(currentStatus)) {
            return (OrderStatus.FINISHED.getKey().equals(targetStatus));
        } else if (OrderStatus.FINISHED.getKey().equals(currentStatus)) {
            return (OrderStatus.AFTER_SALES.getKey().equals(targetStatus));
        } else if (OrderStatus.AFTER_SALES.getKey().equals(currentStatus)) {
            return false;
        } else {
            return false;
        }
    }

    @Override
    public List<OrderStatistics> statistics(Long userId) {
        return baseMapper.statistics(userId);
    }
}
